package org.univie.mappr;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import android.graphics.drawable.Drawable;
import android.util.Log;

/**
 * Stores a defined amount of photo thumbnails locally to retrieve them later
 */
public abstract class ThumbnailCache {

	private static final String TAG = "org.univie.mappr.ThumbnailCache";

	private static final int MAX_CACHED = 200;
	// private static final String CACHE_NAME =
	// "Android/data/org.univie.mappr/files/thumbnailcache/";
	private static final String CACHE_NAME = "MapprThumbnails";
	private static File CACHE_DIR;
	private static File SDCARD;

	/**
	 * Adds the thumbnail for a photo to the cache
	 * 
	 * @param photo
	 */
	public static void addThumbnail(FlickrPhoto photo) {
		Log.d(TAG, "Trying to add thumbnail for photo " + photo.getId());
		try {
			URL thumbnailUrl = photo.getUrl(FlickrPhoto.SIZE_SMALL);
			InputStream in = thumbnailUrl.openStream();
			File outputFile = new File(CACHE_DIR, photo.getId() + ".jpg");
			FileOutputStream fos = new FileOutputStream(outputFile);
			BufferedOutputStream bos = new BufferedOutputStream(fos, 1024);

			byte[] data = new byte[1024];
			int datapart;

			while ((datapart = in.read(data, 0, 1024)) >= 0) {
				bos.write(data, 0, datapart);
			}

			bos.close();
			fos.close();
			in.close();
			
			// If the maximum size of the cache was exceeded, delete the first file
			File file_to_delete = CACHE_DIR.listFiles()[0];
			if (CACHE_DIR.listFiles().length > MAX_CACHED) {
				for(File tmp_file : CACHE_DIR.listFiles()){
					// find the oldest file and delete it
					if(file_to_delete.lastModified() > tmp_file.lastModified()){
						tmp_file = file_to_delete;
					}
				}
				file_to_delete.delete();
			}
		} catch (MalformedURLException e) {
			Log.e(TAG, "Error while downloading thumbnail for photo "
					+ photo.getId());
			e.printStackTrace();
		} catch (IOException e) {
			Log.e(TAG, "Error while downloading thumbnail for photo "
					+ photo.getId());
			e.printStackTrace();
		} catch (Exception e) {
			Log.e(TAG, "General error while writing to the cache");
		}
	}

	/**
	 * Returns a drawable resource of the photo thumbnail
	 * 
	 * @param photo
	 *            The photo for which the resource is requested
	 * @return A drawable thumbnail
	 */
	public static Drawable getDrawable(FlickrPhoto photo) {
		Log.d(TAG, "Creating drawable for photo " + photo.getId());

		// if we did not already have the photo saved or it was deleted or
		// whatever
		if (!hasThumbnail(photo))
			addThumbnail(photo);

		// read the file and create a drawable
		File inputFile = new File(CACHE_DIR, photo.getId() + ".jpg");
		Drawable drawable = Drawable.createFromPath(inputFile.toString());
		return drawable;
	}

	/**
	 * Returns whether the cache has the thumbnail for the photo or not
	 */
	public static boolean hasThumbnail(FlickrPhoto photo) {
		File file = new File(CACHE_DIR, photo.getId() + ".jpg");
		return (file.exists() && file.canRead());
	}

	public static void cleanup() {
		Log.d(TAG, "Deleting files - number of files: "+CACHE_DIR.list().length);
		try {
			for (File to_delete : CACHE_DIR.listFiles()) {
			//	File to_delete = new File(CACHE_DIR, filename + ".jpg");
				to_delete.delete();		
			}
		} catch (Exception e) {
			Log.e(TAG, "Error while cleaning up the cache. Some files might still be left over.");
		}
	}

	/**
	 * 
	 * @return the size of the CacheDir in byte
	 * 
	 */
	public static long get_size(){
		long slh = 0;
		for(File tmp_file : CACHE_DIR.listFiles()){
			slh += tmp_file.length();
		}
		return slh;
	}
	
	/**
	 * Initializes the folders of the cache on the SD card
	 * 
	 * @param sdCard
	 * @throws IOException
	 */
	public static void initialize(File sdCard) throws IOException {
		SDCARD = sdCard;
		CACHE_DIR = new File(SDCARD, CACHE_NAME);
		CACHE_DIR.mkdirs();
	}
	

}
